iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0
Software Development

從零開始構建能理解語義的 Linebot 架構系列 第 13

Kafka 概念介紹及部署: Consumer、Partition 及 Offset 管理

  • 分享至 

  • xImage
  •  

概述

  • 合理的分配Consumer及Partition可以使效能和資源利用最大化: 一個Consumer Group中,理想的Instance數目 = 該Group訂閱的所有Topic的Partiton總數。
  • Kafka透過Offset確認訊息消費的進度,並且需要各個Consumer透過自動,或手動呼叫Consumer API的方式,將消費進度提交到Offset Map。
  • 有了Offset紀錄這些資訊,當Consumer變動時,才能正確地知道上次消費到哪,還有哪些訊息需要被消費
  • 透過一些Kafka提供的工具程式,可以在後端方便地掌握目前的消費狀況,例如提供Consumer Group資訊的/opt/kafka/bin/kafka-consumer-groups.sh

Consumer

在Kafka中,Consumer是負責從Broker拉取資料的實體。每個Consumer會對Broker指定其在某個Partition中的偏移量(Offset),並從該位置開始接收接下來的事件(Event)。
這種機制讓 Consumer 可以準確地從指定的事件開始進行消費,並掌握消費的進度。

Consumer Group與Partiton分配

這邊說明Consumer Group的組成,以及他們是如何被分配到該消費的Partition:

Consumer Instance

  • 一個執行中的Consumer程式。

Consumer Group

  • 由多個Consumer Instance組成的群體,訂閱一個或多個Topic。
  • 每個Consumer Group都有唯一識別的 Group ID,用來區分不同的 Consumer Group。這使得不同的 Consumer Group可以同時消費相同的 Topic,而不會互相干擾。
  • 注意: 一個包含多個Instance的Consumer Group,其功能和單一Consumer Instance是一樣的。他們都是針對訂閱的Topic進行資料消費,差別只是在有多個Instance時,效能會更好。
  • 要使用多個Consumer Instance來改善效能,還需要配合正確的Partition分配。

Partition 分配規則

  • 在同一個Consumer Group中
    • 每個Partition 只能被分配給一個其中一個Consumer Instance進行消費。
  • 而在多個Consumer Group中
    • Partition可以被分配給多個不同Consumer Group的Consumer Instance。

如何決定Consumer Group中的 Instance個數

  • 基本上,一個Consumer Group中,理想的Instance數目 = 該Group訂閱的所有Topic的Partiton總數
  • 例如: 某Consumer Group訂閱了3個Topic,而每個Topic剛好都有2個Partition,則最有效率的Consumer Instance數目,就是 3 * 2 = 6個。多餘的Consumer Instance不會被指派Partition進行消費,會浪費資源。

Offset 管理

  • Offset是每個 Consumer追蹤其消費進度的來源。Kafka需要掌握Offset資訊,當Consumer斷訊,或者要加入 / 抽換Consumer Instance時,才能正確地接手訊息進度,也就是上次消費到哪,還有哪些需要被消費

Offset 管理的特點

  • 很多其他訊息引擎系統也會紀錄Offset,但他們大都是把Offset記錄在中央服務器中(類似Kafka的 Broker)
  • 但這樣的做法會導致Broker不再是無狀態(not stateless),而不利於擴展和彈性。

Offset 管理方式

  • Kafka 採用了一個更簡化的方案,讓每個 Consumer Group 自行管理 Offset,這樣可以減少 Broker 的負擔,並且簡化確認機制。

自動與手動 Commit Offset

  • Kafka 預設會讓Consumer定期自動提交(Commit)Offset,也可以選擇手動透過Consumer API提交 Offset,以便讓開發者自己處理消費進度的更新。
    • 自動提交的設置是enable.auto.commit,預設為true
    • 自動提交預設是每5秒自動提交,可以在Config修改auto.commit.interval.ms來更改間隔時間
  • 每個 Consumer Group 的消費狀態會定期保存到 Kafka的Offset Map中。
  • 例如下圖是test-group這個Consumer group的Offset Map,紀錄了每個被訂閱的Topic中,各Partition的消費狀況:

一些Offset的名詞

以下這些常見名詞經常散落在Kafka的各種GUI介面與Console工具中,它們都和Offset有關。
在進行Debug或者優化效能瓶頸時,理解這些概念非常實用:

Last Committed Offset

  • Consumer Group最後一次成功提交的 Offset,代表這之前的消息都已成功消費。

Current Position

  • Consumer Group當前消費的Offset位置。如果 Current Position 與 Last Committed Offset之間有差距,表示消息已經被拉取但尚未提交(Not Committed)

Log End Offset (LEO)

  • Producer將寫入下一個訊息的位置。

Committed Offset

  • 保存在Broker上的Offset,表示已確認消費過的最終位置。
  • 需要通過Consumer API: commitSync 或 commitAsync來更新,否則不會改變

如何查看 Consumer Group 的 Offset 狀況

  • 除了透過UI以外,Kafka有提供一些Console工具程式可以查看各種資訊
  • 使用kafka-consumer-groups.sh可以查看 Consumer Group 的 Offset 狀況,範例指令如下:
docker exec -it kafka ./opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--describe --group {ConsumerGroup名稱}

此指令會顯示以下關鍵資訊:
https://ithelp.ithome.com.tw/upload/images/20240927/20105227uYNX6z9ulX.png

CURRENT-OFFSET:該 Partition 最後一次提交的 Offset。
LOG-END-OFFSET:此 Partition 的最大 Offset(等同於資料總數)。
LAG:表示 Consumer 與當前最大 Offset 之間的差距。
CLIENT-ID:分配給各 Partition 的 Consumer Instance ID(如果有設置 client.id )。

結論

  • Kafka的Consumer透過Offset機制來控制消費進度,每個Consumer Group紀錄自己的Offset狀態,並且可以選擇自動提交紀錄,或者透過Consumer API自行提交。
  • 透過有效管理 Offset,開發者可以精確掌控消息的處理狀況,並確保訊息保持一致性和順序性。

除了Offset狀態,Consumer與Partition彼此的指派關係,也是Kafka管理的一大重點,根據不同的條件,有時會需要重新指定Partition被消費的對象。這個機制在下一章將繼續說明。

Citation

https://www.cnblogs.com/huxi2b/p/6223228.html


上一篇
Kafka 概念介紹及部署: Topic 及 Producer
下一篇
Kafka 概念介紹及部署: Rebalance機制
系列文
從零開始構建能理解語義的 Linebot 架構30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言